/*
 * group:android.permission-group.CONTACTS
 * permission:android.permission.WRITE_CONTACTS
 * permission:android.permission.GET_ACCOUNTS
 * permission:android.permission.READ_CONTACTS
 * <p>
 * group:android.permission-group.PHONE
 * permission:android.permission.READ_CALL_LOG
 * permission:android.permission.READ_PHONE_STATE
 * permission:android.permission.CALL_PHONE
 * permission:android.permission.WRITE_CALL_LOG
 * permission:android.permission.USE_SIP
 * permission:android.permission.PROCESS_OUTGOING_CALLS
 * permission:com.android.voicemail.permission.ADD_VOICEMAIL
 * <p>
 * group:android.permission-group.CALENDAR
 * permission:android.permission.READ_CALENDAR
 * permission:android.permission.WRITE_CALENDAR
 * <p>
 * group:android.permission-group.CAMERA
 * permission:android.permission.CAMERA
 * <p>
 * group:android.permission-group.SENSORS
 * permission:android.permission.BODY_SENSORS
 * <p>
 * group:android.permission-group.LOCATION
 * permission:android.permission.ACCESS_FINE_LOCATION
 * permission:android.permission.ACCESS_COARSE_LOCATION
 * <p>
 * group:android.permission-group.STORAGE
 * permission:android.permission.READ_EXTERNAL_STORAGE
 * permission:android.permission.WRITE_EXTERNAL_STORAGE
 * <p>
 * group:android.permission-group.MICROPHONE
 * permission:android.permission.RECORD_AUDIO
 * <p>
 * group:android.permission-group.SMS
 * permission:android.permission.READ_SMS
 * permission:android.permission.RECEIVE_WAP_PUSH
 * permission:android.permission.RECEIVE_MMS
 * permission:android.permission.RECEIVE_SMS
 * permission:android.permission.SEND_SMS
 * permission:android.permission.READ_CELL_BROADCASTS
 */
package com.bl.andr.permission;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;

import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import java.util.ArrayList;
import java.util.List;

/**
 * 动态权限申请工具类，
 * 身体传感器  (SENSORS)
 * 日历       (CALENDAR)
 * 摄像头     (CAMERA)
 * 通讯录     (CONTACTS)
 * 地理位置   (LOCATION)
 * 麦克风     (MICROPHONE)
 * 电话       (PHONE)
 * 短信       (SMS)
 * 存储空间   (STORAGE)
 * Created by yubaolin on 2016/12/6 0006.
 */

public class PermissionManager {
    private static final String TAG = PermissionManager.class.getSimpleName();

    private List<String> deniedPermissions = new ArrayList<>();
    private List<String> shouldRationaleList = new ArrayList<>();

    private static final int PERMISSION_REQUEST_CODE = 1;

    private static volatile PermissionManager instanc = null;

    private PermissionManager() {
    }

    public static synchronized PermissionManager getInstance() {
        if (instanc == null) {
            synchronized (PermissionManager.class) {
                if (instanc == null) {
                    instanc = new PermissionManager();
                }
            }
        }
        return instanc;
    }

    private GrantResult mGrantResult;

    // 必须需要开启 是否 需要说明
    private boolean needGrantFlag;

    /**
     * 设置权限申请回调
     */
    public PermissionManager setGrantResult(GrantResult grantResult) {
        mGrantResult = grantResult;
        return this;
    }

    /**
     * 设置权限拒绝后是否需要说明的标识
     */
    public PermissionManager setNeedGrantFlag(boolean needGrantFlag) {
        this.needGrantFlag = needGrantFlag;
        return this;
    }

    /**
     * 申请权限
     *
     * @param permissions 权限
     */
    public void requestPermissions(Activity activity, String... permissions) {

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return;
        if (permissions == null || permissions.length <= 0) return;

        if (checkPermission(activity, permissions)) {
            // 全部已授权
            if (mGrantResult != null) mGrantResult.onGrantedAll();
            return;
        }

        if (deniedPermissions.size() > 0) {
            request(activity, permissions);
        } else if (shouldRationaleList.size() > 0) {
            if (mGrantResult != null) mGrantResult.onExplain(permissions);
        }
    }

    /**
     * 系统权限询问对话框的回调方法
     * 需要在相应的页面重写同名的方法
     */
    @TargetApi(value = Build.VERSION_CODES.M)
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {
        if (requestCode == PERMISSION_REQUEST_CODE) {
            ArrayList<String> notGranted = new ArrayList<>();
            for (int i = 0; i < permissions.length; i++) {
                if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                    notGranted.add(permissions[i]);
                }
            }

            if (notGranted.size() == 0) {
                if (mGrantResult != null) mGrantResult.onGrantedAll();
            } else {
                if (mGrantResult != null) mGrantResult.onDenied(permissions);
            }
        }
    }

    private boolean checkPermission(Activity activity, String... permissions) {
        shouldRationaleList.clear();
        deniedPermissions.clear();
        boolean result = true;
        if (permissions != null && permissions.length > 0) {
            for (String permission : permissions) {
                // 未授权，记录在集合中
                if (!verifyPermission(activity,permission)) {
                    result = false;
                    boolean should = ifShouldRationale(activity, permission);
                    if (should && needGrantFlag) {
                        shouldRationaleList.add(permission);
                    } else {
                        deniedPermissions.add(permission);
                    }
                }
            }
        }

        return result;
    }

    public void request(Activity activity, String... permissions) {
        ActivityCompat.requestPermissions(activity, permissions, PERMISSION_REQUEST_CODE);
    }


    /**
     * 1、如果app之前请求过该权限,被用户拒绝, 这个方法就会返回true.
     * 2、首次申请权限时，放回false
     * 2、如果用户之前拒绝权限的时候勾选了对话框中”Don’t ask again”的选项,那么这个方法会返回false.
     * 3、如果设备策略禁止应用拥有这条权限, 这个方法也返回false.
     */
    private boolean ifShouldRationale(Activity activity, String permission) {
        return ActivityCompat.shouldShowRequestPermissionRationale(activity, permission);
    }


    /**
     * 检查是否授予某项指定的权限
     */
    public static boolean verifyPermission(Context mContext, String permission) {
        return ContextCompat.checkSelfPermission(mContext, permission) ==
                PackageManager.PERMISSION_GRANTED;
    }

    /**
     * 启动应用的设置
     */
    public static void startAppSettings(Context context) {
        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        intent.setData(Uri.parse("package:" + context.getPackageName()));
        context.startActivity(intent);
    }
}
